//-----------------------------------------------------------------------
// <copyright file="ThreadSynchronizatinAcceptanceTest.cs" company="NMock2">
//
//   http://www.sourceforge.net/projects/NMock2
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
// </copyright>
// This is the easiest way to ignore StyleCop rules on this file, even if we shouldn't use this tag:
// <auto-generated />
//-----------------------------------------------------------------------
namespace NMock2.AcceptanceTests
{
    using System.Threading;
    using NUnit.Framework;

    [TestFixture]
    public class ThreadSynchronizationAcceptanceTest : AcceptanceTestBase
    {
        /// <summary>
        /// You can use the <see cref="Signal"/> class to signal event handles when the action on an expectation is executed.
        /// </summary>
        [Test]
        public void SynchronizeThreads()
        {
            AutoResetEvent signalFromBackgroundThread = new AutoResetEvent(false);
            AutoResetEvent signalFromForegroundThread = new AutoResetEvent(false);

            IHelloWorld helloWorld = Mocks.NewMock<IHelloWorld>();

            Expect.Once.On(helloWorld).Method("Hello").Will(Signal.EventWaitHandle(signalFromBackgroundThread));

            ThreadPool.QueueUserWorkItem(delegate
                                             {
                                                 if (signalFromForegroundThread.WaitOne(1000, false))
                                                 {
                                                     helloWorld.Hello(); // this will set the signal
                                                 }
                                             });

            signalFromForegroundThread.Set();
            bool signaled = signalFromBackgroundThread.WaitOne(1000, false);

            Assert.IsTrue(signaled, "did not receive signal from background thread.");
        }
    }
}